crow |
您所在的位置:网站首页 › go-micro v4 › crow |
文章目录
1. 目录结构2. 添加自己的微服务2.1 配置文件和必要的函数2.1.1 配置文件2.1.2 连接k8s
2.2 k8s服务相关代码2.3 proto2.3.1 创建proto文件2.3.2 编译proto
2.4 handler2.5 k8s的main函数
3. gateway调用3.1 调用微服务3.2 router
4. 添加文档 swagger5. 调试5.1 启动服务5.2 swagger接口测试
1. 目录结构
bin 编译好的二进制文件 cmd: 各微服务的main函数和相关初始化函数 docker 容器相关,包括docker-compose.yml和dockerFile internal:内部代码(不需要对外) app:各微服务私有的代码cache:redis相关的代码conf:配置和变量相关的models:数据库相关pkg:各微服务公用的方法等代码pkg:公共代码,外部可能用到的 sql:sql文件 MakeFile README.md 2. 添加自己的微服务已获取k8s的node节点列表为例,写一个k8s的微服务接入crow-han中 2.1 配置文件和必要的函数 2.1.1 配置文件 在cmd目录下创建k8s目录以后放置微服务k8s的main函数、初始化相关代码、配置文件等 该目录下创建etc目录放置配置文件etc目录下创建kube.conf 文件,将k8s服务器master上 ~/.kube/config文件内容拷贝进去。 2.1.2 连接k8s在internal/conf 目录下创建 connect_k8s.go文件 以下这段是链接k8s的代码。这段代码可以作为微服务k8s的私有代码放在internal/app/k8s中,也可以最为脚手架公用配置放在internal/conf中。考虑到我之后将按照crow-han的风格,在微服务k8s的main函数中初始化k8s链接,为避免以后出现循环调用的可能,这里选择了后者。 ackage conf import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) var K8sClientSet *kubernetes.Clientset func ConnectK8s() (clientSet *kubernetes.Clientset, err error) { configPath := "etc/kube.conf" config, err := clientcmd.BuildConfigFromFlags("", configPath) if err != nil { return nil, err } clientSet, err = kubernetes.NewForConfig(config) if err != nil { return nil, err } return clientSet, nil } 2.2 k8s服务相关代码在internal/app下添加k8s目录(放置该微服务处理逻辑的一些代码),在下边创建 nodes.go文件(放置node操作相关的代码,我们这里写一个获取nodeList作为示例)。 package service import ( "context" "crow-han/internal/conf" coreV1 "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func GetNodeList() (nodeList *coreV1.NodeList, err error) { nodeList, err = conf.K8sClientSet.CoreV1().Nodes().List(context.TODO(), metaV1.ListOptions{}) if err != nil { return nodeList, err } return nodeList, nil } 2.3 proto 2.3.1 创建proto文件 在proto目录下创建k8s目录,下边创建k8s.proto文件 syntax = "proto3"; package k8s; option go_package = "./proto/k8s;k8s"; service K8s { rpc GetNodeList(GetNodeListRequest) returns (GetNodeListResponse) {} } message GetNodeListRequest { } message GetNodeListResponse { string NodeList = 1; }GetNodeListResponse这个是微服务返回给gateway的返回值,GetNodeList() 返回是*coreV1.NodeList,通常我们可以转换成proto的格式。但是因为这个node返回值比较复杂,所以这里我返回一个字串(json)然后在gateway再解析回来。 2.3.2 编译proto 编译proto protoc --proto_path=. --micro_out=. --go_out=:. proto/k8s/k8s.proto 生成文件 此时 proto/k8s目录下生成k8s.pb.go k8s.pb.micro.go两个文件 2.4 handler在internal/app/k8s目录下创建 /handler目录,下边创建 nodes.go 文件 package handler import ( "context" "crow-han/internal/app/k8s/service" pb "crow-han/proto/k8s" "encoding/json" "github.com/toolkits/pkg/logger" ) type Nodes struct{} func (e *Nodes) GetNodeList(ctx context.Context, req *pb.GetNodeListRequest, rsp *pb.GetNodeListResponse) error { logger.Infof("Received K8s.GetNodeList request: %v", req) nodeList, err := service.GetNodeList() if err != nil { logger.Error(err) return err } output, err := json.Marshal(&nodeList) if err != nil { logger.Error(err) } rsp.NodeList = string(output) return nil } 2.5 k8s的main函数在cmd目录下创建k8s目录,目录下创建main.go文件,内容如下 package k8s import ( "crow-han/internal/app/k8s/handler" "crow-han/internal/cache" "crow-han/internal/conf" pb "crow-han/proto/k8s" "fmt" "github.com/go-micro/plugins/v4/registry/consul" "github.com/kelseyhightower/envconfig" "go-micro.dev/v4/registry" "go-micro.dev/v4" "go-micro.dev/v4/logger" ) func init() { //初始化变量 err := envconfig.Process("crow", &conf.MyEnvs) if err != nil { fmt.Println(err) } fmt.Printf("%+v\n", &conf.MyEnvs) //初始化日志 conf.LoggerInit() logger.Info("logger init") //mysql初始化 var tx conf.MyConnect tx.ConnectMysql() //初始化redis //redis初始化 conf.RedisConnect() cache.CheckRides() //初始化k8s conf.K8sClientSet, err = conf.ConnectK8s() if err != nil { fmt.Println(err) } } var ( service = "k8s" version = "latest" ) func main() { // Create service srv := micro.NewService() consulRegis := consul.NewRegistry(func(options *registry.Options) { options.Addrs = []string{ conf.MyEnvs.ConsulAddr, } }) srv.Init( micro.Name(service), micro.Version(version), micro.Registry(consulRegis), ) // Register handler if err := pb.RegisterK8SHandler(srv.Server(), new(handler.Nodes)); err != nil { logger.Fatal(err) } if err := srv.Run(); err != nil { logger.Fatal(err) } } 3. gateway调用 3.1 调用微服务在internal/app/gate-way/service目录下创建k8s_nodes.go文件,内容如下: package service import ( "context" k8sProto "crow-han/proto/k8s" "encoding/json" "github.com/gin-gonic/gin" "github.com/toolkits/pkg/logger" coreV1 "k8s.io/api/core/v1" ) func GetNodeList(c *gin.Context) { //调用k8s userSrv := k8sProto.NewK8SService("k8s", srv.Client()) respSr, err := userSrv.GetNodeList(context.Background(), &k8sProto.GetNodeListRequest{}) logger.Infof("%+v", respSr) if err != nil { logger.Error(err) SetErr(c, 500, err, err.Error()) return } //将结果转换为原结构体 var resp *coreV1.NodeList json.Unmarshal([]byte(respSr.NodeList), &resp) SetOK(c, resp) } 3.2 router在internal/app/gate-way/service/router.go文件中添加一条路由规则 func ServerRouter() { …… groupV1 := r.Group("/api/v1") { …… groupV1.GET("/k8s/node/list", user(), GetNodeList) //添加这条路由 }说明:需要user验证的加上验证方法 user(),不想验证可以不加。 4. 添加文档 swagger 在internal/app/gate-way/service/k8s_nodes.go文件的GetNodeList()函数前添加如下注释 // GetNodeList 查看node列表 // @Summary 查看node列表 // @Description 查看node列表 // @Tags Node // @Success 200 {object} response.Response{data=v1.NodeList} "{"requestId": "string","code": 200,"msg": "ok","data": [...]}" // @Failure 500 {object} response.Response{msg=string} "{"requestId": "string","code": 500,"msg": "string","status": "error","data": null}" // @Router /api/v1/k8s/node/list [get] // @Security Bearer func GetNodeList(c *gin.Context) { …… }详细方法见另一篇博文《GO语言gin框架实战-03-swagger和接口文档》 编译swagger cd internal/app/gate-way/service swag init --parseDependency --parseInternal --parseDepth 2 -g .\router.go 5. 调试 5.1 启动服务按上一章 《crow-han(基于go-micro框架的微服务脚手架)-01-快速启动》方法配置数据库并启动gate-way、auth、user。 goland配置k8s服务并启动 consul上查看 我们新写的微服务注册上来了 ![]() ![]() ![]() 输出如下: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |